using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

using Game.Networking.Utils;

using TMPro;
using Voxels;

namespace Game.UI {
	public sealed class MainMenu : MonoBehaviour {
		public Button			  StartServerButton  = null;
		public Button			  JoinGameButton     = null;
		public Button			  LocalGameButton    = null;
		public Button			  QuitButton         = null;
		public TMP_InputField	  IpInput            = null;
		public TMP_InputField	  NameInput          = null;
		public TMP_InputField	  PasswordInput      = null;
		public GameObject		  LoadingScreen      = null;
		public DisconnectedWindow DisconnectedWindow = null;

		void InitStaticSystems() {
			//Обязательная инициализация обвязки воксельной системы:
			Shader.SetGlobalColor("_SunGlobalColor", Color.white);
			var blockLib = Resources.Load<ResourceLibrary>("ResourceLibrary");
			StaticResources.BlocksInfo = new BlockInfoProvider(blockLib.BlockDescriptions);
			var tilesetHelper = new TilesetHelper(16, 512);
			BlockModelGenerator.PrepareGenerator(tilesetHelper);
		}

		void Start() {
			InitStaticSystems();
			DisconnectedWindow.gameObject.SetActive(false);
			LoadingScreen.SetActive(false);
			StartServerButton.onClick.AddListener(StartServer);
			JoinGameButton.onClick.AddListener(JoinGame);
			LocalGameButton.onClick.AddListener(LocalGame);
			QuitButton.onClick.AddListener(QuitGame);

			if ( Application.isBatchMode ) {
				Application.targetFrameRate = 60;
				StartServer();
			} else {
#if UNITY_EDITOR
				QualitySettings.vSyncCount = 0;
				Application.targetFrameRate = 60;
#else
				QualitySettings.vSyncCount = 1;
#endif
			}

			if ( NetworkOptions.ClientDisconnectReason != DisconnectReason.Unknown) {
				var message = "Connection lost";
				switch ( NetworkOptions.ClientDisconnectReason ) {
					case DisconnectReason.Unknown:
						break;
					case DisconnectReason.NoConnection:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "No connection to the server" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.TimeOut:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "Connection time out" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.ServerAlreadyStarted:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "Server already running" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.DifferentProtocol:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "Different protocol version" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.Kicked:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "You are kicked from the server" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.Banned:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "You are banned on the server" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.ServerShutdown:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "Server shutting down" : NetworkOptions.DisconnectMessage;
						break;
					case DisconnectReason.ConnectionLost:
						message = string.IsNullOrEmpty(NetworkOptions.DisconnectMessage) ? "Connection lost" : NetworkOptions.DisconnectMessage;
						break;
					default:
						break;
				}
				DisconnectedWindow.Show(message);
			}
		}

		void StartServer() {
			StartGame(false, true);
		}

		void JoinGame() {
			StartGame(true, false);
		}

		void LocalGame() {
			IpInput.text = NetworkOptions.Localhost;
			StartGame(true, true);
		}

		void QuitGame() {
			Application.Quit();
		}

		void StartGame(bool isClient, bool isServer) {
			if ( !string.IsNullOrEmpty(IpInput.text) ) {
				NetworkOptions.ServerIP = IpInput.text;
			}
			if ( !string.IsNullOrEmpty(NameInput.text) ) {
				NetworkOptions.PlayerName = NameInput.text;
			}
			if ( !string.IsNullOrEmpty(PasswordInput.text) ) {
				NetworkOptions.Password = PasswordInput.text;
			}
			NetworkOptions.ClientDisconnectReason = DisconnectReason.Unknown;
			NetworkOptions.StartClient = isClient;
			NetworkOptions.StartServer = isServer;
			LoadingScreen.SetActive(true);
			if ( isServer) {
				SceneManager.LoadScene("Server");
			} else if ( isClient) {
				SceneManager.LoadScene("Client");
			}			
		}
	}
}
